﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Dynamic;

using ElfDoc;

namespace DocumentModelFake
{

    class TestableModel
    {

        public static DocumentModel GetModelTestData()
        {
            #region object data ...

            var model = new DocumentModel();

            model.CaseConductor = new CaseConductor();

            model.CaseConductor.Person = new List<Person>();
            model.CaseConductor.Person.Add(new Person());

            model.CaseConductor.Person[0].Surname = "{Smith}";
            model.CaseConductor.Person[0].DOB = DateTime.Now;

            model.CaseConductor.Person[0].Forename = "{John}";
            model.CaseConductor.Person[0].GenderEnum = GenderEnum.Male;
            model.CaseConductor.Person[0].Email = "{jk@co.com}";
            model.CaseConductor.Person[0].FaxNumber = "{Fax}";
            model.CaseConductor.Person[0].MobileNumber = "{Mobile}";
            model.CaseConductor.Person[0].PhoneNumber = "{Ph}";
            model.CaseConductor.Person[0].WorkPhone = "{WkPh}";

            model.CaseConductor.CaseNoteList = new List<Note>();
            model.CaseConductor.CaseNoteList.Add(new Note { NoteID = Guid.NewGuid(), NoteText = "A-1", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.CaseNote });
            model.CaseConductor.CaseNoteList.Add(new Note { NoteID = Guid.NewGuid(), NoteText = "B-2", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.ReferralNote });
            model.CaseConductor.CaseNoteList.Add(new Note { NoteID = Guid.NewGuid(), NoteText = "C-3", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.ReferralNote });

            model.CaseConductor.CaseWorkerList = new List<CaseWorker>();
            model.CaseConductor.CaseWorkerList.Add(new CaseWorker { CaseWorkerID = Guid.NewGuid(), DisplayName = "CWA" });
            model.CaseConductor.CaseWorkerList.Add(new CaseWorker { CaseWorkerID = Guid.NewGuid(), DisplayName = "CWB" });
            model.CaseConductor.CaseWorkerList.Add(new CaseWorker { CaseWorkerID = Guid.NewGuid(), DisplayName = "CWC" });
            #endregion
            //-Return
            return model;

        }
    }

    public enum NoteTypeEnum
    {
        Root = 0,
        ReferralNote = 1,
        CaseNote = 2,
        StatusNote = 3,
    }

    public class CaseWorker
    {
        public Guid CaseWorkerID { get; set; }
        public string DisplayName { get; set; }
    }

    public class Note
    {
        public Guid NoteID { get; set; }
        public string NoteText { get; set; }
        public NoteTypeEnum NoteTypeEnum { get; set; }
        public DateTime? NoteDt { get; set; }
        public Guid? PersonID { get; set; }
        public string DisplayName { get; set; }
    }

    public enum GenderEnum
    {
        NotSpecified = 0,
        Male = 1,
        Female = 2,
        NotKnown = 3
    }

    public partial class Person
    {
        public Guid PersonID { get; set; }
        public string Surname { get; set; }
        public string Forename { get; set; }
        public string PhoneNumber { get; set; }
        public string MobileNumber { get; set; }
        public string WorkPhone { get; set; }
        public GenderEnum GenderEnum { get; set; }
        public string FaxNumber { get; set; }
        public string Email { get; set; }
        public string Title { get; set; }
        public bool IsAdUser { get; set; }
        public bool IsAspNetUser { get; set; }

        public DateTime? DOB { get; set; }
        public int Age()
        {
            int ageNow = 0;
            TimeSpan ts = new TimeSpan();

            if (this.DOB != null)
            {
                ts = DateTime.Now - this.DOB.Value;
            }

            return ts.Days / 356;
        }

    }

    public partial class Case
    {
        public Guid CaseID { get; set; }
        public string CaseRef { get; set; }
    }

    public class CaseConductor
    {

        public List<Case> Case { get; set; }
        public List<Person> Person { get; set; }
        public List<Note> CaseNoteList { get; set; }
        public List<CaseWorker> CaseWorkerList { get; set; }

        public void Load(Guid caseID)
        {
            this.Case = new List<Case>();
            this.Case.Add(new Case { CaseID = caseID, CaseRef = "10010001" });

            this.CaseNoteList = new List<Note>();
            this.CaseNoteList.Add(new Note { NoteID = Guid.NewGuid(), NoteText = "A-1", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.CaseNote });
            this.CaseNoteList.Add(new Note { NoteID = Guid.NewGuid(), NoteText = "B-2", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.ReferralNote });
            this.CaseNoteList.Add(new Note { NoteID = Guid.NewGuid(), NoteText = "C-3", NoteDt = DateTime.Now, NoteTypeEnum = NoteTypeEnum.ReferralNote });

        }

    }

    public class DocumentModel : DynamicDictionary
    {
        public Guid CaseID { get; set; }
        public CaseConductor CaseConductor { get; set; }
    }

    enum WidgetEnum
    {
        OneEnum = 1,
        TwoEnum = 2
    }

    enum WidgetEnumOther
    {
        X1Enum = 1,
        X2Enum = 2
    }

    class Widget
    {
        public int foo1()
        {
            return 1;
        }
        public string foo2(string parm)
        {
            return parm;
        }
        public int foo3(int parm)
        {
            return parm;
        }
        public string foo4(int parm1, string parm2)
        {
            return parm1.ToString() + parm2;
        }
        public string foo5(int parm1, string parm2, long parm3)
        {
            return parm1.ToString() + parm2 + parm3.ToString();
        }
        public string foo6(int parm1, string parm2, long parm3, bool parm4)
        {
            return parm1.ToString() + parm2 + parm3.ToString() + parm4.ToString();
        }
        public string foo7(int parm1, string parm2, long parm3, bool parm4, float parm5)
        {
            return parm1.ToString() + parm2 + parm3.ToString() + parm4.ToString() + parm5.ToString();
        }
        public string foo8(int parm1, string parm2, long parm3, bool parm4, float parm5, double parm6)
        {
            return parm1.ToString() + parm2 + parm3.ToString() + parm4.ToString() + parm5.ToString() + parm6.ToString();
        }
        public string foo9(WidgetEnum widgetEnum)
        {
            return widgetEnum.ToString();
        }
        public string foo10(WidgetEnumOther widgetEnum)
        {
            return widgetEnum.ToString();
        }

    }


    public partial class MultiFake
    {

        public Guid PersonID { get; set; }
        public string Surname { get; set; }
        public string Forename { get; set; }
        public string PhoneNumber { get; set; }
        public string MobileNumber { get; set; }
        public string WorkPhone { get; set; }
        public GenderEnum GenderEnum { get; set; }
        public string FaxNumber { get; set; }
        public string Email { get; set; }
        public string Title { get; set; }
        public bool IsAdUser { get; set; }
        public bool IsAspNetUser { get; set; }

        public DateTime? DOB { get; set; }
        public int Age()
        {
            int ageNow = 0;
            TimeSpan ts = new TimeSpan();
            if (this.DOB != null)
            {
                ts = DateTime.Now - this.DOB.Value;
            }
            return ts.Days / 356;
        }

        public void FooCausesExceptionOnInside()
        {
            throw new ApplicationException("Thrown by FooCausesExceptionOnInside()");
        }

    }

    // The class derived from DynamicObject.
    //http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject(VS.100).aspx
    public class DynamicDictionary : DynamicObject
    {

        // The inner dictionary.
        Dictionary<string, object> dictionary = new Dictionary<string, object>();

        public ValueByKeyTuple ValueByKeyTuple(string key)
        {

            Dictionary<string, int> dottedContext = new Dictionary<string, int>();
            if (this.dictionary.ContainsKey("dottedcontext"))
            {
                dottedContext = this.dictionary["dottedcontext"] as Dictionary<string, int>;
            }

            //-Return
            return ElfDoc.ElfDocHelper.ValueByKeyTuple(this, key, dottedContext);
        }

        // This property returns the number of elements
        // in the inner dictionary.
        public int DynamicObjectCount
        {
            get
            {
                return dictionary.Count;
            }
        }

        // If you try to get a value of a property 
        // not defined in the class, this method is called.
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {

            // Converting the property name to lowercase
            // so that property names become case-insensitive.
            string name = binder.Name.ToLower();

            // If the property name is found in a dictionary,
            // set the result parameter to the property value and return true.
            // Otherwise, return false.
            return dictionary.TryGetValue(name, out result);

        }

        // If you try to set a value of a property that is
        // not defined in the class, this method is called.
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {

            // Converting the property name to lowercase
            // so that property names become case-insensitive.
            dictionary[binder.Name.ToLower()] = value;

            // You can always add a value to a dictionary,
            // so this method always returns true.
            return true;
        }

    }

}      


